package internal

import (
	"fmt"
	"io"
	"net"
	"serverlog/global"
	"serverlog/src/internal/icode"
)

type Session struct {
	id     uint32
	conn   net.Conn
	quit   chan uint32
	notify chan iinternal.INotifyMsg
}

func NewSession(id uint32, quit chan uint32, conn net.Conn, notify chan iinternal.INotifyMsg) iinternal.ISession {
	return &Session{
		id:     id,
		conn:   conn,
		quit:   quit,
		notify: notify,
	}
}

func (s *Session) GetId() uint32 {
	return s.id
}

func (s *Session) Run() {
	defer func() {
		s.quit <- s.id
	}()

	//头部
	hd := NewHeadPkt()
	hdbuf := make([]byte, hd.GetHeadLen())
	databuf := make([]byte, global.ServerGlobal.MaxBufLen)
	for {
		_, err := io.ReadFull(s.conn, hdbuf)
		if err != nil {
			fmt.Println("conn read err=", err)
			break
		}
		if err := hd.UnPack(hdbuf); err != nil {
			fmt.Println("headpkt unpack err=", err)
			break
		}
		// fmt.Println("recv data id=", hd.Id, " data len=", hd.Len)
		//判断下数据长度是否合法
		if hd.Len > global.ServerGlobal.MaxBufLen {
			fmt.Println("data len is too long")
			break
		}

		//数据
		n, err := io.ReadFull(s.conn, databuf[:hd.Len])
		if err != nil {
			fmt.Println("conn read data err=", err)
			break
		}
		s.msgProc(hd, databuf[:n])
	}
}

func (s *Session) msgProc(hd *HeadPkt, data []byte) error {
	switch hd.Id {
	case 0:
		logpkt := NewLogPkt()
		if err := logpkt.UnPack(data); err != nil {
			fmt.Println("logpkt unpack err=", err)
			break
		}
		logpkt.Msg = data[logpkt.GetHeadLen():]
		msg := NewNotifyMsg()
		msg.SetLevel(logpkt.Level)
		msg.SetMsg(string(logpkt.Msg))
		s.notify <- msg
	}

	return nil
}
